/**
 *   DataSlim - Lazy Loading Framework
 *   Copyright (C) 2007 Rodolfo Dias
 *   
 *   This program is free software; you can redistribute it and/or modify
 *   it under the terms of the GNU General Public License as published by
 *   the Free Software Foundation; either version 2 of the License, or
 *   (at your option) any later version.
 *
 *   This program is distributed in the hope that it will be useful,
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *   GNU General Public License for more details.
 *
 *   You should have received a copy of the GNU General Public License along
 *   with this program; if not, write to the Free Software Foundation, Inc.,
 *   51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * 
 */

package net.dataslim.processor;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.Reader;
import java.lang.reflect.Method;
import java.net.URL;
import java.util.HashMap;
import java.util.Map;

import com.sun.mirror.apt.AnnotationProcessorEnvironment;

public abstract class SimpleTemplateVisitor  {
	
		AnnotationProcessorEnvironment env;
		
		Map<String, String> mapMethods = new HashMap<String, String>(){{
			put("package.qualifiedName", "visitorPackage");
			put("class.simpleName", "visitorNameClass");
			put("class.type", "visitorTypeClass");
			put("class.simpleName.field", "visitorField");
			put("class.methods", "visitorMethods");
		}};
		
		public SimpleTemplateVisitor(AnnotationProcessorEnvironment env){
			this.env = env;
		}
		
		public void accept(){
			BufferedReader readerTemplate = null;
			try{
				readerTemplate = toReader(getTemplate());
				if (readerTemplate.ready()){
					String line = null;
					while((line = readerTemplate.readLine()) != null){
						line = visitorLine(line);
					}
				}else{
					env.getMessager().printError("Nao foi possivel abrir o arquivo de template");
				}
			}catch(Exception e){
				e.printStackTrace();
			}finally{
				closeReader(readerTemplate);
			}
			endTemplate();
		}
		
		
		protected String visitorLine(String line){
			//System.out.println("valor original:"+line);
			String analyseLine = line;
			int sinalMenor = analyseLine.indexOf("<");
			if (sinalMenor != -1){
				do{
					int sinalMaior = analyseLine.indexOf(">", sinalMenor)+1;
					String chave = analyseLine.substring(sinalMenor, sinalMaior);
					analyseLine = analyseLine.substring(sinalMaior);
					line = visitor(chave, line);
					//System.out.println(chave);
					//System.out.println("Restou: " + analyseLine);
				}while( (sinalMenor = analyseLine.indexOf("<")) != -1);
			}
			return line;
		}
		
				
		public String visitor(String chave, String line){
			chave = parserChave(chave);
			String nameMethod = mapMethods.get(chave.trim());
			if (nameMethod == null)return line;
			try{
				Method m = this.getClass().getMethod(nameMethod, new Class[]{String.class});
				return (String) m.invoke(this, new Object[]{line});
			}catch(Exception e){
				e.printStackTrace();
			}
			return "";
		}
		
		public abstract String visitorPackage(String line);
		
		public abstract String visitorNameClass(String line);
		
		public abstract String visitorTypeClass(String line);
		
		public abstract String visitorField(String line);
	
		public abstract String visitorMethods(String line);
		
		public abstract URL getTemplate();
		
		
		public void endTemplate(){
		}
		
		private void closeReader(Reader r){
			try{
				if (r != null) r.close();
			}catch(Exception e){
				
			}
		}
		
		protected String replace(String line, String chave, String valor){
			int indexOfLine = -1;
			String newLine = line;
			while ( (indexOfLine = line.indexOf(chave)) != -1){
				newLine = line.substring(0, indexOfLine);
				newLine += valor;
				newLine += line.substring(line.indexOf(">", indexOfLine)+1);
				line = newLine;
			}
			return newLine;
		}
		
		private BufferedReader toReader(URL urlFile){
			BufferedReader readerTemplate = null;
			try{
				readerTemplate = new BufferedReader(new InputStreamReader(urlFile.openStream()));
			}catch(Exception e){
				
			}
			return readerTemplate;
		}
		
		private String parserChave(String chave){
			if (chave.startsWith("</")){
				chave = chave.substring(2, chave.length()-1);
			}else if (chave.indexOf(" ") != -1){
				chave = chave.substring(1, chave.indexOf(" ")+1);
			}else if (chave.indexOf("/>") != -1){
				chave = chave.substring(1, chave.length()-2);
			}else{
				chave = chave.substring(1, chave.length()-1);
			}
			return chave;
		}
}

